#include <evalsoc.h>
#include  <stdio.h>
#include  <string.h>

#include "test_dma.h"
#include "evalsoc_uart.h"


/**
 * brief: DMA初始化函数，配置DMA通道为Memory to Memory模式
 * @param channer: DMA通道号
 * @param src_addr: DMA通道的源地址
 * @param dst_addr: DMA通道的目的地址
 * @param len: BLOCK_TS
 */
void dma_init_M2M(uint16_t channer,uint32_t src_addr,uint32_t dst_addr,uint32_t len) {   

    struct dw_dma_regs *dma_regs = (struct dw_dma_regs *)0x00100000;

    dma_regs->CFG = DW_CFG_DMA_EN; // Enable DMA controller


    dma_regs->CHAN[channer].SAR = src_addr; // Source Address Register
    dma_regs->CHAN[channer].DAR = dst_addr; // Destination Address Register



    dma_regs->CHAN[channer].CTL_LO = DWC_CTLL_FC_M2M | DWC_CTLL_SRC_WIDTH(0x0) |DWC_CTLL_DST_WIDTH(0x0)| DWC_CTLL_DST_FIX |
    DWC_CTLL_SRC_MSIZE(0x1) | DWC_CTLL_DST_MSIZE(0x1) | DWC_CTLL_INT_EN;
    // memory to memory;源传输宽度：0x2-32位;目的传输宽度：0x2-32位;源地址增量默认：递增;目的地址增量：0x2-不变;
    //源突发事务长度：0x1-4;目的突发事务长度：0x1-4;中断使能：使能;

    dma_regs->CHAN[channer].CTL_HI = len ;// BLOCK_TS

    dma_regs->CH_EN = 0x101 << channer; // Enable DMA channel



}
//Memory to Peripheral flow controller:DMA
/**
 * brief: DMA初始化函数，配置DMA通道为Memory to Peripheral模式
 * @param channer: DMA通道号
 * @param dma_req: DMA请求号
 * @param src_addr: DMA通道的源地址
 * @param dst_addr: DMA通道的目的地址
 * @param width: 传输宽度
 * @param msize: 突发事务长度
 * @param len: BLOCK_TS
 *  
 */
void dma_init_M2P(uint32_t channer,uint32_t dma_req,uint32_t src_addr,uint32_t dst_addr,uint32_t width,uint32_t  msize,uint32_t len) {   
    
    struct dw_dma_regs *dma_regs = (struct dw_dma_regs *)0x00100000;

    dma_regs->CFG = DW_CFG_DMA_EN; // Enable DMA controller


    dma_regs->CHAN[channer].CTL_LO = DWC_CTLL_FC_M2P | DWC_CTLL_SRC_WIDTH(width) |DWC_CTLL_DST_WIDTH(width)|  DWC_CTLL_DST_FIX |
    DWC_CTLL_SRC_MSIZE(msize) | DWC_CTLL_DST_MSIZE(msize) | DWC_CTLL_INT_EN;

    dma_regs->CHAN[channer].CTL_HI = len ;// BLOCK_TS


    dma_regs->CHAN[channer].CFG_HI = dma_req<<11;


    dma_regs->CHAN[channer].CFG_LO = 0;

    
    dma_regs->CHAN[channer].SAR = src_addr; // Source Address Register
    dma_regs->CHAN[channer].DAR = dst_addr; // Destination Address Register

    __RWMB();


    dma_regs->CH_EN = 0x101 << channer; // Enable DMA channel

    
}

//  Peripheral to Memory flow controller:DMA
/**
 * brief: DMA初始化函数，配置DMA通道为 Peripheral to Memory 模式
 * @param channer: DMA通道号
 * @param dma_req: DMA请求号
 * @param src_addr: DMA通道的源地址
 * @param dst_addr: DMA通道的目的地址
 *  @param width: 传输宽度 0x0-8位 0x1-16位 0x2-32位
 * @param msize: 突发事务数量 0x0-1 0x1-4 0x2-8 0x3-16
 * @param len: BLOCK_TS
 * 
 */
void dma_init_P2M(uint16_t channer,uint16_t dma_req,uint32_t src_addr,uint32_t dst_addr,uint32_t width,uint32_t  msize,uint32_t len) {  

    struct dw_dma_regs *dma_regs = (struct dw_dma_regs *)0x00100000;

    dma_regs->CFG = DW_CFG_DMA_EN; // Enable DMA controller


    dma_regs->CHAN[channer].CTL_LO = DWC_CTLL_FC_P2M | DWC_CTLL_SRC_WIDTH(width) |DWC_CTLL_DST_WIDTH(width)|  DWC_CTLL_SRC_FIX |
    DWC_CTLL_SRC_MSIZE(msize) | DWC_CTLL_DST_MSIZE(msize) | DWC_CTLL_INT_EN;

    dma_regs->CHAN[channer].CTL_HI = len ;// BLOCK_TS

    dma_regs->CHAN[channer].CFG_LO = 0|DWC_CFGL_HS_SRC_POL;

    dma_regs->CHAN[channer].CFG_HI = dma_req<<7;

    
    dma_regs->CHAN[channer].SAR = src_addr; // Source Address Register
    dma_regs->CHAN[channer].DAR = dst_addr; // Destination Address Register

    //__RWMB();

    dma_regs->CH_EN = 0x101 << channer; // Enable DMA channel

}






